home *** CD-ROM | disk | FTP | other *** search
- // -------------------------------------------------------------------------------------
- // Thread safe printf(), sprintf(), fprintf(), scanf(), fscanf(), sscanf(), etc.
- // -------------------------------------------------------------------------------------
- // Permission is granted to freely redistribute this source code, and to use fragments
- // of this code in your own applications if you find them to be useful. This module,
- // along with the source code, come with no warranty of any kind, and the user assumes
- // all responsibility for its use.
- // -------------------------------------------------------------------------------------
- #import <mach/cthreads.h>
- #import <libc.h>
- #import <math.h>
- #import <stdlib.h>
- #import <stdio.h>
- #import <stdarg.h>
- #import <string.h>
- #import <streams/streams.h>
-
- // -------------------------------------------------------------------------------------
- static char didInit = 0;
- static mutex_t protecto = (mutex_t)0;
-
- // -------------------------------------------------------------------------------------
- #define INIT if (!didInit) thread_initStdio()
- #define LOCK mutex_lock(protecto)
- #define UNLOCK mutex_unlock(protecto)
- #define _DO_SCAN 1
-
- // -------------------------------------------------------------------------------------
- // thread protected io initialization routine
- void thread_initStdio()
- {
- if (didInit) return;
- protecto = mutex_alloc();
- didInit = 1;
- }
-
- // -------------------------------------------------------------------------------------
- // <x>printf
-
- /* vprintf() */
- int thread_vprintf(const char *fmt, va_list arg)
- {
- int rtn;
- INIT; // initialize
- LOCK;
- rtn = vprintf(fmt, arg);
- UNLOCK;
- return rtn;
- }
-
- /* printf() */
- int thread_printf(const char *fmt, ...)
- {
- int rtn;
- va_list arg;
- va_start(arg, fmt);
- rtn = thread_vprintf(fmt, arg);
- va_end(arg);
- return rtn;
- }
-
- /* fprintf() */
- int thread_vfprintf(register FILE *fhnd, const char *fmt, va_list arg)
- {
- int rtn;
- INIT; // initialize
- LOCK;
- rtn = vfprintf(fhnd, fmt, arg);
- UNLOCK;
- return rtn;
- }
-
- /* fprintf() */
- int thread_fprintf(register FILE *fhnd, const char *fmt, ...)
- {
- int rtn;
- va_list arg;
- va_start(arg, fmt);
- rtn = thread_vfprintf(fhnd, fmt, arg);
- va_end(arg);
- return rtn;
- }
-
- /* vsprintf() */
- int thread_vsprintf(char *str, const char *fmt, va_list arg)
- {
- int rtn;
- INIT; // initialize
- LOCK;
- rtn = vsprintf(str, fmt, arg);
- UNLOCK;
- return rtn;
- }
-
- /* sprintf() */
- int thread_sprintf(char *str, const char *fmt, ...)
- {
- int rtn;
- va_list arg;
- va_start(arg, fmt);
- rtn = thread_vsprintf(str, fmt, arg);
- va_end(arg);
- return rtn;
- }
-
- // -------------------------------------------------------------------------------------
- // <x>scanf
-
- /* vfscanf() */
- int thread_vfscanf(FILE *fhnd, const char *fmt, va_list arg)
- {
- int rtn;
- #ifdef _DO_SCAN
- extern int _doscan(FILE*, const char*, va_list);
- #endif
- INIT; // initialize
- LOCK;
- #ifdef _DO_SCAN
- //#warning Implementing 'thread_vfscanf()' with '_doscan()'
- rtn = _doscan(fhnd, fmt, arg);
- #else
- //#warning Implementing 'thread_vfscanf()' with 'NXVScanf()'
- if (fhnd->_flag & _IOSTRG) {
- NXStream *s = NXOpenMemory(fhnd->_ptr, fhnd->_cnt, NX_READONLY);
- rtn = NXVScanf(s, fmt, arg);
- NXCloseMemory(s, NX_FREEBUFFER);
- } else {
- NXStream *s = NXOpenFile(fileno(fhnd), NX_READONLY);
- rtn = NXVScanf(s, fmt, arg);
- NXClose(s);
- }
- #endif
- UNLOCK;
- return rtn;
- }
-
- /* fscanf() */
- int thread_fscanf(FILE *fhnd, const char *fmt, ...)
- {
- va_list arg;
- int rtn;
- va_start(arg, fmt);
- rtn = thread_vfscanf(fhnd, fmt, arg);
- va_end(arg);
- return rtn;
- }
-
-
- /* scanf() */
- int thread_scanf(const char *fmt, ...)
- {
- va_list arg;
- int rtn;
- va_start(arg, fmt);
- rtn = thread_vfscanf(stdin, fmt, arg);
- va_end(arg);
- return rtn;
- }
-
- /* sscanf() */
- int thread_sscanf(register const char *str, const char *fmt, ...)
- {
- va_list arg;
- int rtn;
- FILE f;
- va_start(arg, fmt);
- f._base = f._ptr = (char*)str;
- f._bufsiz = f._cnt = strlen(str);
- f._flag = _IOREAD | _IOSTRG;
- rtn = thread_vfscanf(&f, fmt, arg);
- va_end(arg);
- return rtn;
- }
-